
/**
 * 泛型：可以传递类型的参数，成为泛型
 * 
 * 泛型参数，要求都是 大写字母：K、T、V、P、S、R
 */
function createArr<K>(num: number, item: K): K[] {
    let arr: K[] = [];
    for (let i = 0; i < num; i++) {
        arr[i] = item;
    }
    return arr;
}

console.log(createArr<string>(3, 'a')); // ['a','a','a']
console.log(createArr<number>(2, 99)); // [99,99]


// 泛型参数可以不止一个
function createArray<T, P>(a: T, b: P): [T, P] {
    return [a, b]
}

console.log(createArray<number, string>(1, 'abc'))


// 泛型接口
interface IResponse<T> {
    code: number;
    msg: string;
    data: T
}

interface IBook {
    id: string;
    name: string;
    author: string;
}
interface ITodo {
    id: string;
    title: string;
    isDone: boolean;
}

let data1: IResponse<IBook> = {
    code: 200,
    msg: '成功',
    data: {
        id: 'adfd123',
        name: '葵花宝典',
        author: '东方不败'
    }
}

let data2: IResponse<ITodo> = {
    code: 200,
    msg: '获取数据成功',
    data: {
        id: '123',
        title: '吃饭',
        isDone: true
    }
}

// 泛型类：用泛型限定类
class Container<T>{
    //用于储存数据
    store: T[];
    constructor(store: T[]) {
        this.store = store;
    }
}

let books = new Container<IBook>([
    { id: 'ab123', name: '西游记', author: '吴承恩' },
    { id: 'sx23', name: '三国演义', author: '罗贯中' }
])

let todos = new Container<ITodo>([
    { id: 'sfre1', title: 'chifan', isDone: true }
])

// 泛型约束
// function fn<T>(x: T): void {
//     // console.log(x.length)  // error
// }
// fn(2);
// fn(true);
// fn([1,2,3]);
// fn('abc');


interface Lengthwise {
    length: number;
}

// 指定泛型约束
/**
 *  泛型是一种特殊类型的接口
 *  T 必须拥有length属性
 *  如果有length属性 就默认继承了Lengthwise接口
 */
function fn2<T extends Lengthwise>(x: T): void {
    console.log(x.length)
}

fn2('abc')
// fn2(123);
fn2([1,2,3])

export { }